package com.lin.blog.controller;

import com.lin.blog.entity.UserFrom;
import com.lin.blog.service.IUserService;
import com.lin.constant.JwtConstant;
import com.lin.constant.RedisConstant;
import com.lin.shiro.utils.JwtUtil;
import com.lin.utils.RedisUtils;
import com.lin.utils.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresUser;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/**
 * @program: blog
 * @description: 登录控制器
 * @author: Lin
 * @create: 2020-04-27 11:06
 **/
@Api(tags = "Login接口")
@RestController
public class LoginController {

    @Autowired
    private IUserService userService;

    private static Logger logger = LoggerFactory.getLogger(UserController.class);

    @ApiOperation("后台登出")
    @ApiImplicitParam(name = "token", value = "token",required = true)
    @PostMapping("/admin/logout")
    public Result adminLogout(String token){
        return userService.adminLogout(token);
    }


    /**
     * 通过账号密码Token
     * @param userFrom
     * @return
     */
    @ApiOperation("后台登录 通过账号密码Token")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username", value = "用户账号",required = true),
            @ApiImplicitParam(name = "password", value = "用户密码", required = true)})
    @PostMapping("/admin/login")
    public Result getTokenByUserNameAndPassword(@Validated @RequestBody UserFrom userFrom){
        String username = userFrom.getUsername();
        String password = userFrom.getPassword();
        UsernamePasswordToken token = new UsernamePasswordToken(username,password);
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);

        }catch (IncorrectCredentialsException e){
            logger.info("密码不正确");
            throw new IncorrectCredentialsException();
        }catch (UnknownAccountException e1){
            logger.info("账号不正确");
            throw new UnknownAccountException();
        }

        if(subject.isAuthenticated()){
            // 验证通过
            JwtUtil jwtUtil = new JwtUtil();
            Map<String, Object> map = new HashMap<>(16);
            map.put("username", username);
            map.put("password", password);

            // accessToken
            String accessToken = jwtUtil.encode(JwtConstant.JWT_ISS, JwtConstant.JWT_ACCESS_TOKEN_EXPIRE_TIME_MILLIS, map);


            // 缓存到Redis中
            RedisUtils.set(username+ RedisConstant.JWT_ACCESS_TOKEN_SUFFIX ,accessToken,RedisConstant.JWT_ACCESS_TOKEN_EXPIRE);
            Map<String,String> tokenInfo = new HashMap(16);
            tokenInfo.put("accessToken",accessToken);
            return Result.success(tokenInfo);

        }
        return Result.failureMessage("登录失败");
    }


}
